#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义联系人结构体
typedef struct Contact {
    char name[50];          // 姓名
    char phone[20];         // 电话号码
    struct Contact* next;   // 指向下一个联系人的指针
} Contact;

// 全局变量：通讯录链表头指针
Contact* head = NULL;

// 函数声明
void printMenu();
void addContact();
void deleteContact();
void displayContacts();
void searchContact();
void saveToFile();
void loadFromFile();
void freeContacts();

int main() {
    int choice;

    // 主循环
    while (1) {
        printMenu();        // 打印菜单
        printf("请输入选项: ");
        scanf("%d", &choice);

        // 清除输入缓冲区
        while (getchar() != '\n');

        switch (choice) {
        case 1:
            addContact();      // 添加联系人
            break;
        case 2:
            deleteContact();   // 删除联系人
            break;
        case 3:
            displayContacts(); // 显示所有联系人
            break;
        case 4:
            searchContact();   // 搜索联系人
            break;
        case 5:
            saveToFile();      // 保存到文件
            break;
        case 6:
            loadFromFile();    // 从文件加载
            break;
        case 0:
            freeContacts();     // 释放内存
            printf("感谢使用通讯录系统，再见！\n");
            exit(0);            // 退出程序
        default:
            printf("无效选项，请重新输入！\n");
        }
    }
    return 0;
}

// 打印主菜单
void printMenu() {
    printf("\n===== 通讯录管理系统 =====\n");
    printf("1. 添加联系人\n");
    printf("2. 删除联系人\n");
    printf("3. 显示所有联系人\n");
    printf("4. 查找联系人\n");
    printf("5. 保存到文件\n");
    printf("6. 从文件加载\n");
    printf("0. 退出系统\n");
    printf("==========================\n");
}

// 添加联系人
void addContact() {
    // 创建新节点
    Contact* newContact = (Contact*)malloc(sizeof(Contact));
    if (newContact == NULL) {
        printf("内存分配失败！\n");
        return;
    }

    // 获取用户输入
    printf("请输入姓名: ");
    fgets(newContact->name, sizeof(newContact->name), stdin);
    newContact->name[strcspn(newContact->name, "\n")] = '\0'; // 移除换行符

    printf("请输入电话号码: ");
    fgets(newContact->phone, sizeof(newContact->phone), stdin);
    newContact->phone[strcspn(newContact->phone, "\n")] = '\0'; // 移除换行符

    // 将新节点添加到链表头部
    newContact->next = head;
    head = newContact;

    printf("联系人添加成功！\n");
}

// 删除联系人
void deleteContact() {
    if (head == NULL) {
        printf("通讯录为空！\n");
        return;
    }

    char name[50];
    printf("请输入要删除的联系人姓名: ");
    fgets(name, sizeof(name), stdin);
    name[strcspn(name, "\n")] = '\0'; // 移除换行符

    Contact* current = head;
    Contact* previous = NULL;
    int found = 0;

    // 遍历链表查找联系人
    while (current != NULL) {
        if (strcmp(current->name, name) == 0) {
            found = 1;
            break;
        }
        previous = current;
        current = current->next;
    }

    if (found) {
        // 删除节点
        if (previous == NULL) {
            head = current->next; // 删除头节点
        }
        else {
            previous->next = current->next; // 删除中间或尾部节点
        }
        free(current);
        printf("联系人已删除！\n");
    }
    else {
        printf("未找到该联系人！\n");
    }
}

// 显示所有联系人
void displayContacts() {
    if (head == NULL) {
        printf("通讯录为空！\n");
        return;
    }

    printf("\n===== 通讯录列表 =====\n");
    Contact* current = head;
    int count = 1;

    // 遍历并打印所有联系人
    while (current != NULL) {
        printf("%d. 姓名: %-20s 电话: %s\n", count++, current->name, current->phone);
        current = current->next;
    }
    printf("=======================\n");
}

// 查找联系人
void searchContact() {
    if (head == NULL) {
        printf("通讯录为空！\n");
        return;
    }

    char name[50];
    printf("请输入要查找的联系人姓名: ");
    fgets(name, sizeof(name), stdin);
    name[strcspn(name, "\n")] = '\0'; // 移除换行符

    Contact* current = head;
    int found = 0;

    // 遍历链表查找联系人
    while (current != NULL) {
        if (strcmp(current->name, name) == 0) {
            printf("\n===== 找到联系人 =====\n");
            printf("姓名: %s\n", current->name);
            printf("电话: %s\n", current->phone);
            printf("======================\n");
            found = 1;
            break;
        }
        current = current->next;
    }

    if (!found) {
        printf("未找到该联系人！\n");
    }
}

// 保存到文件
void saveToFile() {
    if (head == NULL) {
        printf("通讯录为空，无需保存！\n");
        return;
    }

    FILE* file = fopen("contacts.txt", "w");
    if (file == NULL) {
        printf("无法打开文件！\n");
        return;
    }

    Contact* current = head;
    // 遍历链表并将数据写入文件
    while (current != NULL) {
        fprintf(file, "%s,%s\n", current->name, current->phone);
        current = current->next;
    }

    fclose(file);
    printf("通讯录已保存到文件！\n");
}

// 从文件加载
void loadFromFile() {
    // 先清空当前通讯录
    freeContacts();
    head = NULL;

    FILE* file = fopen("contacts.txt", "r");
    if (file == NULL) {
        printf("文件不存在或无法打开！\n");
        return;
    }

    char line[100];
    // 逐行读取文件
    while (fgets(line, sizeof(line), file)) {
        // 创建新节点
        Contact* newContact = (Contact*)malloc(sizeof(Contact));
        if (newContact == NULL) {
            printf("内存分配失败！\n");
            break;
        }

        // 解析数据
        char* name = strtok(line, ",");
        char* phone = strtok(NULL, "\n");

        if (name && phone) {
            strcpy(newContact->name, name);
            strcpy(newContact->phone, phone);

            // 添加到链表头部
            newContact->next = head;
            head = newContact;
        }
    }

    fclose(file);
    printf("通讯录已从文件加载！\n");
}

// 释放链表内存
void freeContacts() {
    Contact* current = head;
    while (current != NULL) {
        Contact* temp = current;
        current = current->next;
        free(temp);
    }
    head = NULL;
}